//抽象类
//通常情况下【父类表示约束统一特征】，没有实际意义
//限制公有类[父类]做实例化对象操作：抽象类
//关键字：abstract  写在class之前
//抽象类不能实例化对象！
//抽象类可以属性，可以写普通方法！ 也可以写抽象方法[用abstract修饰，方法没有方法体]
//抽象方法：没有方法体的方法，只能写在抽象类中，使用关键字abstract
//子类一旦继承抽象父类，就必须重写父类的抽象方法
//抽象类还是类，类里面还是会包含：构造函数、属性、方法
//             描述特征，和普通类无差别
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
//抽象父类
var Pet = /** @class */ (function () {
    function Pet() {
    }
    return Pet;
}());
// class Animal{
//     public name:string;
//     public show():void{
//         console.log("业务逻辑")
//     }
//     //public abstract test():void;
// }
var Dog = /** @class */ (function (_super) {
    __extends(Dog, _super);
    function Dog() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    Dog.prototype.test = function () {
        //逻辑代码
        console.log("dog子类方法");
    };
    return Dog;
}(Pet));
var Cat = /** @class */ (function (_super) {
    __extends(Cat, _super);
    function Cat() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    Cat.prototype.test = function () {
        console.log("cat子类方法");
    };
    return Cat;
}(Pet));
//var myPet = new Pet();//父类不能实例化了
var dog = new Dog();
//dog.test();
var cat = new Cat();
var petArr = [dog, cat];
petArr[0].test();
petArr[1].test();
var Lei = /** @class */ (function () {
    function Lei() {
    }
    Lei.prototype.gongneng1 = function () {
        console.log("方法体");
    };
    return Lei;
}());
//抽象父类：描述特征的
var FuLei = /** @class */ (function () {
    function FuLei() {
    }
    return FuLei;
}());
var MyTestClass = /** @class */ (function (_super) {
    __extends(MyTestClass, _super);
    function MyTestClass() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    //父类约束必须具有的公共特征
    MyTestClass.prototype.show = function () {
        console.log("父类约束的show方法");
    };
    //接口约束必须具备的特有特征
    MyTestClass.prototype.test = function () {
        console.log("接口约束的test方法");
    };
    MyTestClass.prototype.test1 = function () {
        console.log("接口约束的test1方法");
    };
    MyTestClass.prototype.test2 = function () {
        console.log("另一个接口约束的test2方法");
    };
    return MyTestClass;
}(FuLei));
//var jk = new JK1();不能实例化
var mtc = new MyTestClass();
mtc.show();
mtc.test();
mtc.test1();
mtc.test2();
mtc.name = "";
mtc.age = 1;
var bl;
bl = {
    test: function () {
        console.log("实现接口的方法");
    }
};
console.log(bl);
var info;
info = {
    num: 10,
    str: "abc",
    show: function () {
        console.log('111');
    }
};
var Teacher = /** @class */ (function () {
    function Teacher() {
        this.num = 1;
        this.str = "";
    }
    Teacher.prototype.show = function () {
        console.log('111');
    };
    return Teacher;
}());
var shuju;
shuju = {
    num: 1,
    str: "",
    show: function () {
    }
};
var sj;
sj = {
    name: "",
    age: 1
};
//非泛型：
//在定义时就定下类型
// function fun(num:number){
// }
// fun(123)
//泛型：约束类型，当运行时才定下类型
//语法：
//    实际使用时写 <类型>  来代替 编码时写 <T>
//在函数名之后写<T>来说明 后续参数和返回值是何类型
function fn(num) {
    return num;
}
var result = fn(123);
console.log(typeof (result));
var result2 = fn("str");
console.log(typeof (result2));
